/*
 *  main.h
 *  Preview3D
 *
 *  Created by Alec Jacobson on 11/15/10.
 *  Copyright 2010 New York University. All rights reserved.
 *
 */

#ifdef __APPLE__
#define _MACOSX
#endif
#include <AntTweakBar.h>

#include <vector>

////////////////////////////////////////////////////////////////////////////////
// Global variables
////////////////////////////////////////////////////////////////////////////////
std::vector<std::vector<double> > vertices;
size_t number_of_vertices = 0;
std::vector<std::vector<size_t> > faces;
size_t number_of_faces = 0;
std::vector<std::vector<double> > face_normals;
std::vector<std::vector<double> > vertex_normals;

////////////////////////////////////////////////////////////////////////////////
// Convenient Math helper functions
////////////////////////////////////////////////////////////////////////////////
void SetQuaternionFromAxisAngle(const float *axis, float angle, float *quat);
void ConvertQuaternionToMatrix(const float *quat, float *mat);
void MultiplyQuaternions(const float *q1, const float *q2, float *qout);

////////////////////////////////////////////////////////////////////////////////
// Rendering variables
////////////////////////////////////////////////////////////////////////////////
// Scene scale
float g_Zoom = 1.0f;
// zoom and shift are set once when mesh is loaded to center and normalize
// shape to fit unit box
float zoom = 1.0f;
float shift[] = {0.0f,0.0f,0.0f};
// Shape orientation (stored as a quaternion)
float g_Rotation[] = { 0.0f, 0.0f, 0.0f, 1.0f };
// Auto rotate
bool g_AutoRotate = 0;
int g_RotateTime = 0;
float g_RotateStart[] = { 0.0f, 0.0f, 0.0f, 1.0f };
// Shapes material
// Grey
//float g_MatAmbient[] = { 0.2f, 0.2f, 0.2f, 1.0f };
//float g_MatDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
// Gold
float g_MatAmbient[] = { 51.0/255.0,43.0/255.0,33.3/255.0,1.0f };
float g_MatDiffuse[] = { 255.0/255.0,228.0/255.0,58.0/255.0,1.0f };
float g_MatSpecular[] = { 255.0/255.0,235.0/255.0,80.0/255.0,1.0f };
float g_MatShininess = 35.;
float background_color[] = { 0.3f, 0.3f, 0.5f, 1.0f };
float line_color[] = {0.0f,0.0f,0.0f,1.0f};
// Light parameter
float g_LightMultiplier = 1.0f;
float g_LightDirection[] = { -0.57735f, -0.57735f, -0.57735f };
bool flat_shading = true;
bool show_faces = true;
bool show_lines = true;

////////////////////////////////////////////////////////////////////////////////
// Rendering functions
////////////////////////////////////////////////////////////////////////////////
//  Callback function called when the 'AutoRotate' variable value of the tweak bar has changed
void TW_CALL SetAutoRotateCB(const void *value, void *clientData);
//  Callback function called by the tweak bar to get the 'AutoRotate' value
void TW_CALL GetAutoRotateCB(void *value, void *clientData);
// Callback function called by GLUT to render screen
void Display(void);
// Callback function called by GLUT when window size changes
void Reshape(int width, int height);
// Function called at exit
void Terminate(void);
// push scene matrices
void push_scene();
// pop scene matrices
void pop_scene();
// draw a mesh
void draw_mesh(
  const std::vector<std::vector<double> > & vertices, 
  const std::vector<std::vector<size_t> > & faces,
  bool show_lines,
  float line_color[4],
  bool show_faces,
  bool flat_shading);

////////////////////////////////////////////////////////////////////////////////
// Mesh functions
////////////////////////////////////////////////////////////////////////////////
void compute_face_normals(
  const std::vector<std::vector<double> > & vertices, 
  const std::vector<std::vector<size_t> > & faces,
  std::vector<std::vector<double> > & face_normals);
void compute_vertex_normals(
  const std::vector<std::vector<double> > & vertices, 
  const std::vector<std::vector<size_t> > & faces,
  std::vector<std::vector<double> > & vertex_normals);
bool read_obj(
    char* obj_file_name,
    std::vector<std::vector<double> > & vertices, 
    std::vector<std::vector<size_t> > & faces);
void get_scale_and_shift_to_fit_mesh(
  const std::vector<std::vector<double> > & vertices, 
  const std::vector<std::vector<size_t> > & faces,
  float & zoom,
  float shift[]);
